package com.giventime.stormcoming.units;

import com.giventime.stormcoming.StormComing;
import com.giventime.stormcoming.fights.FightResult;
import com.giventime.stormcoming.utils.StormDungeonUtils.ContentType;
import com.giventime.stormcoming.utils.StormDungeonUtils.HeroClass;

public class StormHero extends StormUnit {

	private HeroClass heroClass;
	private int experience;
	
	/**
	 * 
	 * @param name
	 * @param heroClass
	 * @param contentType
	 */
	public StormHero(String name, HeroClass heroClass, ContentType contentType) {
		super(name, contentType);
		this.heroClass = heroClass;
		hitPoints = heroClass.getHealth()*10;
		experience = 1;
	}

	/**
	 * 
	 */
	public void reset() {
		hitPoints = heroClass.getHealth()*10;
		dead = false;
	}
	
	/**
	 * 
	 * @return
	 */
	public HeroClass getHeroClass() {
		return heroClass;
	}
	
	/**
	 * @return the experience
	 */
	public int getExperience() {
		return experience;
	}

	/**
	 * @param experience the experience to set
	 */
	public void setExperience(int experience) {
		this.experience = experience;
	}

	@Override
	public synchronized void performAttacks(StormUnit enemy) {
		try {
			for (Ability ability : heroClass.getAbilities()) {
				StormComing.addMessage("Hero "+getName()+" casts "+ability.getName());
				enemy.receiveDamage(calculateDamage(ability.getDamage(), ability.getCoefficient()), heroClass.getAccuracy());
				wait(100);
			}			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * @see com.giventime.stormcoming.units.StormUnit#calculateDamage(int, double)
	 */
	@Override
	public int calculateDamage(int damage, double coefficient) {
		int critical = (int) ((Math.round(Math.random()*heroClass.getAccuracy()))*(getLvl()*1.1));
		System.out.println("Hero "+getName()+" gained "+critical+" extra damage due to a well placed strike!");
		return (int) (damage+critical+(heroClass.getDamage()*coefficient));
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.giventime.stormcoming.units.StormUnit#calculateResistances()
	 */
	@Override
	public int calculateResistances() {
		return (int) (heroClass.getResistance()*0.5*getLvl());
	}

	/*
	 * (non-Javadoc)
	 * @see com.giventime.stormcoming.units.StormUnit#evade(int)
	 */
	@Override
	public boolean evade(int accuracy) {
		int evade = (int) Math.round(Math.random()*heroClass.getAvoidance())*(getLvl()/2);
		int toHit = (int) Math.round(Math.random()*accuracy);		
		return evade > toHit;
	}
	
	/*
	 * (non-Javadoc)
	 * @see com.giventime.stormcoming.units.StormUnit#victory(com.giventime.stormcoming.fights.FightResult)
	 */
	@Override
	public void victory(FightResult result) {
		StormComing.addMessage(getName()+" is victorious!");
		int experienceGained = (result.getFallen().getLvl()/2)*10;
		int newExperience = getExperience()+experienceGained;
		System.out.println("calculating experience..."+newExperience);		
		while (newExperience > getLvl()*10) {
			int expToLevel = getLvl()*10;
			System.out.println("Woot, we gained a lvl!");
			newExperience -= expToLevel;
			setLvl(getLvl()+1);
			StormComing.addMessage(getName()+" has reached a new level: "+getLvl());
		}
		StormComing.addMessage(getName()+" gained "+experienceGained+" experience!");
		setExperience(experienceGained);
	}

}
